package org.koin.dsl;

import org.koin.core.definition.BeanDefinition;
import org.koin.core.definition.Definition;
import org.koin.core.definition.Definitions;
import org.koin.core.definition.Options;
import org.koin.core.error.DefinitionOverrideException;
import org.koin.core.module.Module;
import org.koin.core.qualifier.Qualifier;
import java.util.ArrayList;
import java.util.HashSet;

public class ScopeDSL {

    private Qualifier scopeQualifier;
    private HashSet<BeanDefinition> definitions;

    public ScopeDSL(Qualifier scopeQualifier, HashSet<BeanDefinition> definitions) {
        this.scopeQualifier = scopeQualifier;
        this.definitions = definitions;
    }

    public <T> BeanDefinition<T> single(
            Qualifier qualifier,
            boolean override,
            Definition<T> definition
    ) {
        throw new IllegalStateException("Scoped definition is deprecated "
                + "and has been replaced with Single scope definitions");
    }

    public <T> BeanDefinition<T> scoped(
            Class<T> clazz,
            Qualifier qualifier,
            boolean override,
            Definition<T> definition
    ) throws DefinitionOverrideException {

        Options options = new Options()
                .setCreatedAtStart(false)
                .setOverride(override);

        BeanDefinition def = Definitions.INSTANCE().createSingle(
                clazz,
                qualifier,
                definition,
                options,
                new ArrayList<>(),
                scopeQualifier
        );
        Module.addDefinition(definitions, def);
        return def;
    }

    public <T> BeanDefinition<T> scoped(
            Class<T> clazz,
            Definition<T> definition
    ) throws DefinitionOverrideException {
        return this.scoped(clazz, null, false, definition);
    }

    public <T> BeanDefinition<T> factory(
            Class<T> clazz,
            Qualifier qualifier,
            boolean override,
            Definition<T> definition
    ) throws DefinitionOverrideException {
        Options options = new Options()
                .setCreatedAtStart(false)
                .setOverride(override);

        BeanDefinition def = Definitions.INSTANCE().createFactory(
                clazz,
                qualifier,
                definition,
                options,
                new ArrayList<>(),
                scopeQualifier
        );
        Module.addDefinition(definitions, def);
        return def;
    }
}
